package com.dding.cms.base.web;

import static com.dding.cms.base.web.ActionConstants.PIC_UPLOAD_PATH;
import static com.dding.cms.base.web.util.Utils.formatPath;

import java.io.File;
import java.io.IOException;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.dding.core.annotation.Service;
import org.dding.core.log.ILogger;
import org.dding.core.log.LoggerFactory;
import org.dding.core.util.StringUtils;
import org.dding.mvc.ActionSupport;
import org.dding.mvc.InvocationContext;
import org.dding.mvc.PageContext;
import org.dding.mvc.annotation.ActionMethod;

import com.dding.cms.base.service.ImageService;
import com.dding.cms.base.service.impl.ImageServiceImpl;
import com.dding.cms.base.web.bo.MarkConfigBO;
import com.dding.cms.base.web.bo.UploadFileInvocation;
import com.dding.cms.base.web.util.Configuration;
import com.dding.cms.base.web.util.ImageCut;
import com.dding.cms.base.web.util.UploadUtils;

@Service(name = "imgAction")
public class ImgAction extends ActionSupport<Object> {

	private ILogger logger = LoggerFactory.getLogger(getClass());
	private ImageService imageService = new ImageServiceImpl();

	@ActionMethod(
			name = "o_upload_image", errorView = "error.html",
			successView = "common/iframe_upload.jsp",
			httpMethod = ActionMethod.HttpMethod.POST,
			invocationClass = UploadFileInvocation.class)
	public void o_upload_image(InvocationContext invocationContext) {
		UploadFileInvocation invocation = (UploadFileInvocation) invocationContext
				.getInvocation();

		try {
			String path = saveImg(invocationContext.getParameterMap(),
					invocation, invocationContext.getWebPath());
			invocationContext.getPageContext().setAttribute("uploadPath", path);
		} catch (Throwable e) {
			logger.error(e);
			invocationContext.getPageContext().setAttribute(ERRORMESSAGE, e);
		}

		invocationContext.getPageContext().setAttribute("uploadNum",
				invocationContext.getParameterValue("uploadNum"));
	}

	@ActionMethod(
			name = "v_image_area_select", errorView = "error.html",
			successView = "common/image_area_select.jsp",
			httpMethod = ActionMethod.HttpMethod.GET,
			invocationClass = UploadFileInvocation.class)
	public void imageAreaSelect(InvocationContext invocationContext) {

		PageContext model = invocationContext.getPageContext();
		model.setAttribute("uploadBase",
				invocationContext.getParameterValue("uploadBase"));
		model.setAttribute("imgSrcPath",
				invocationContext.getParameterValue("imgSrcPath"));
		model.setAttribute("zoomWidth",
				invocationContext.getParameterValue("zoomWidth"));
		model.setAttribute("zoomHeight",
				invocationContext.getParameterValue("zoomHeight"));
		model.setAttribute("uploadNum",
				invocationContext.getParameterValue("uploadNum"));
	}

	@ActionMethod(
			name = "o_image_cut", errorView = "error.html",
			successView = "common/image_cuted.jsp",
			httpMethod = ActionMethod.HttpMethod.POST,
			invocationClass = UploadFileInvocation.class)
	public void imageCut(InvocationContext invocationContext) {

		String imgSrcPath = invocationContext.getParameterValue("imgSrcPath");
		try {
			Integer imgTop = Integer.valueOf(invocationContext
					.getParameterValue("imgTop"));
			Integer imgLeft = Integer.valueOf(invocationContext
					.getParameterValue("imgLeft"));
			Integer imgWidth = Integer.valueOf(invocationContext
					.getParameterValue("imgWidth"));
			Integer imgHeight = Integer.valueOf(invocationContext
					.getParameterValue("imgHeight"));
			Integer reMinWidth = Integer.valueOf(invocationContext
					.getParameterValue("reMinWidth"));
			Integer reMinHeight = Integer.valueOf(invocationContext
					.getParameterValue("reMinHeight"));
			Float imgScale = Float.valueOf(invocationContext
					.getParameterValue("imgScale"));
			Integer uploadNum = Integer.valueOf(invocationContext
					.getParameterValue("uploadNum"));

			if (imgWidth > 0) {
				ImageCut imageCut = new ImageCut(
						invocationContext.getWebPath(), imgTop, imgLeft,
						imgWidth, imgHeight, reMinWidth, reMinHeight,
						imgSrcPath, imgScale);
				imageService.resizeFixImg(imageCut);

			} else {
				imageService.resizeFixImg(invocationContext.getWebPath(),
						imgSrcPath, reMinWidth, reMinHeight);
			}
			invocationContext.getPageContext().setAttribute("uploadNum",
					uploadNum);
		} catch (Exception e) {
			logger.error(e, "cut image error");
			invocationContext.getPageContext().setAttribute(ERRORMESSAGE,
					e.getMessage());
		}
	}

	public String saveImg(Map<String, String[]> parameters,
			UploadFileInvocation invocation, String webPath) throws Throwable {

		String imagePath = (String) Configuration.getBaseConfig().get(
				PIC_UPLOAD_PATH);

		String fileName = invocation.getFiledata().getFilename();

		File file = formatPath(webPath, imagePath);
		if (file == null) {
			logger.warn("can't upload file,because of folder is not exist.");
			return imagePath;
		}
		boolean mark = Boolean.parseBoolean(parameters.get("mark")[0]);
		MarkConfigBO conf = Configuration.getMarConfig();
		if (!StringUtils.isBlank(fileName)) {
			if (mark) {
				String path = System.getProperty("java.io.tmpdir");
				File ttFile = new File(path, String.valueOf(System
						.currentTimeMillis()));
				FileUtils.writeByteArrayToFile(ttFile, invocation.getFiledata()
						.getContent());
				File tempFile = imageService.mark(ttFile, conf, webPath);
				storeFile(file, fileName, tempFile);
				tempFile.delete();
			} else {
				storeFile(file, invocation.getFiledata().getContent(), fileName);
			}
		} else {
			String ext = FilenameUtils.getExtension(fileName).toLowerCase(
					Locale.ENGLISH);
			fileName = UploadUtils.generateFilename(ext);
			if (mark) {
				String path = System.getProperty("java.io.tmpdir");
				File ttFile = new File(path, String.valueOf(System
						.currentTimeMillis()));
				FileUtils.writeByteArrayToFile(ttFile, invocation.getFiledata()
						.getContent());
				File tempFile = imageService.mark(ttFile, conf, webPath);
				storeFile(file, fileName, tempFile);
				tempFile.delete();
			} else {
				storeFile(file, invocation.getFiledata().getContent(), fileName);
			}
		}
		return imagePath + fileName;
	}

	private void storeFile(File destPath, String fileName, File srcFile) {
		try {
			File destFile = new File(destPath, fileName);
			FileUtils.copyFile(srcFile, destFile);
		} catch (IOException e) {
			logger.error("write upload file " + fileName + " fialue.");
		}
	}

	private void storeFile(File destPath, byte[] content, String fileName) {

		File destFile = new File(destPath, fileName);
		try {
			FileUtils.writeByteArrayToFile(destFile, content);
		} catch (IOException e) {
			logger.error("write upload file " + fileName + " fialue.");
		}
	}
}